#include "../include/rw_png.h"

inline void setRGB (png_byte *ptr, float val);

int writeImage(char* filename, int *buffer, char* title, int Size)
{
    int x, y;
    int maior = buffer[0];
    int menor = buffer[0];
    int code = 0;
    FILE *fp;
    png_structp png_ptr;
    png_infop info_ptr;
    png_bytep row;

    // Open file for writing (binary mode)
    fp = fopen(filename, "wb");
    if (fp == NULL) {
	    fprintf(stderr, "Could not open file %s for writing\n", filename);
	    code = 1;
	    goto finalise;
    }

    // Initialize write structure
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png_ptr == NULL) {
	    fprintf(stderr, "Could not allocate write struct\n");
	    code = 1;
	    goto finalise;
    }

    // Initialize info structure
    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
	    fprintf(stderr, "Could not allocate info struct\n");
	    code = 1;
	    goto finalise;
    }

    // Setup Exception handling
    if (setjmp(png_jmpbuf(png_ptr))) {
	    fprintf(stderr, "Error during png creation\n");
	    code = 1;
	    goto finalise;
    }

    png_init_io(png_ptr, fp);

    // Write header (8 bit colour depth)
    png_set_IHDR(png_ptr, info_ptr, Size, Size,
		    8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
		    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

    // Set title
    if (title != NULL) {
	    png_text title_text;
	    title_text.compression = PNG_TEXT_COMPRESSION_NONE;
	    title_text.key = "Title";
	    title_text.text = title;
	    png_set_text(png_ptr, info_ptr, &title_text, 1);
    }

    png_write_info(png_ptr, info_ptr);

    // Allocate memory for one row (3 bytes per pixel - RGB)
    row = (png_bytep) malloc(3 * Size * sizeof(png_byte));

    //define maio e menor elemento
    //********************************
    int i;
    for ( i = 0; i < (Size*Size); i++ )
	if ( buffer[i] > maior )
	    maior = buffer[i];
	    else
		if ( buffer[i] < menor )
		    menor = buffer[i];
    //********************************

    float num;
    for (y=0 ; y<Size ; y++) {
	    for (x=0 ; x<Size ; x++) {
		    num = (float)((float)( buffer[y*Size + x] - menor)/(maior - menor) );
		    setRGB(&(row[x*3]), num );
	    }
	    png_write_row(png_ptr, row);
    }

    // End write
    png_write_end(png_ptr, NULL);

    finalise:
    if (fp != NULL) fclose(fp);
    if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
    if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
    if (row != NULL) free(row);

    return code;
}

inline void setRGB (png_byte *ptr, float val)
{
	int offset;
	double v = (double)(val * 768);
	if (v > 768) v = 768;

	if ( v != 0 )
	{
	    //printf("Valor Diferente de Zero: %f\n", v );
	    int valor = (int) v;

	    if (valor < 1) valor = 1;
	    offset = valor % 256;

	    if (valor < 256) {
		    ptr[0] = 0; ptr[1] = 0; ptr[2] = offset;
	    }
	    else if (valor < 512) {
		    ptr[0] = 0; ptr[1] = offset; ptr[2] = 255-offset;
	    }
	    else {
		    ptr[0] = offset; ptr[1] = 255-offset; ptr[2] = 0;
	    }
	}
	else
	{
	    v = 0;

	    if ( v == 0 ){
		    ptr[0] = 255; ptr[1] = 255; ptr[2] = 255;
		    //cont++;
	    }
	}
}
